using WeatherSystem.API.CQRS.Commands;
using WeatherSystem.API.Models;
using WeatherSystem.API.Repositories;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.CQRS.Handlers
{
    public class CreateWeatherDataCommandHandler : ICommandHandler<CreateWeatherDataCommand, Guid>
    {
        private readonly IWeatherService _weatherService;
        private readonly ILogger<CreateWeatherDataCommandHandler> _logger;

        public CreateWeatherDataCommandHandler(IWeatherService weatherService, ILogger<CreateWeatherDataCommandHandler> logger)
        {
            _weatherService = weatherService;
            _logger = logger;
        }

        public async Task<Guid> HandleAsync(CreateWeatherDataCommand command)
        {
            try
            {
                // 使用现有服务方法创建天气数据
                var request = new CreateDynamicWeatherDataRequest
                {
                    CityId = command.CityId,
                    RecordedAt = command.RecordedAt,
                    Source = command.Source,
                    Metrics = command.Metrics ?? new Dictionary<string, object>()
                };

                var createdIds = await _weatherService.CreateWeatherDataBatchAsync(new List<CreateDynamicWeatherDataRequest> { request });
                var weatherData = new WeatherDataEntry { Id = createdIds.First() };
                _logger.LogInformation("成功创建天气数据，ID: {WeatherDataId}", weatherData.Id);
                return weatherData.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建天气数据失败");
                throw;
            }
        }
    }

    public class CreateWeatherDataBatchCommandHandler : ICommandHandler<CreateWeatherDataBatchCommand, List<Guid>>
    {
        private readonly IWeatherService _weatherService;
        private readonly ILogger<CreateWeatherDataBatchCommandHandler> _logger;

        public CreateWeatherDataBatchCommandHandler(IWeatherService weatherService, ILogger<CreateWeatherDataBatchCommandHandler> logger)
        {
            _weatherService = weatherService;
            _logger = logger;
        }

        public async Task<List<Guid>> HandleAsync(CreateWeatherDataBatchCommand command)
        {
            try
            {
                var requests = command.WeatherDataList.Select(w => new CreateDynamicWeatherDataRequest
                {
                    CityId = w.CityId,
                    RecordedAt = w.RecordedAt,
                    Source = w.Source,
                    Metrics = w.Metrics ?? new Dictionary<string, object>()
                }).ToList();

                var createdIds = await _weatherService.CreateWeatherDataBatchAsync(requests);
                _logger.LogInformation("成功批量创建天气数据，共 {Count} 条", createdIds.Count);
                return createdIds;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量创建天气数据失败");
                throw;
            }
        }
    }

    public class UpdateWeatherDataCommandHandler : ICommandHandler<UpdateWeatherDataCommand, bool>
    {
        private readonly IWeatherService _weatherService;
        private readonly ILogger<UpdateWeatherDataCommandHandler> _logger;

        public UpdateWeatherDataCommandHandler(IWeatherService weatherService, ILogger<UpdateWeatherDataCommandHandler> logger)
        {
            _weatherService = weatherService;
            _logger = logger;
        }

        public async Task<bool> HandleAsync(UpdateWeatherDataCommand command)
        {
            try
            {
                var request = new UpdateDynamicWeatherDataRequest();
                if (command.CityId.HasValue) request.CityId = command.CityId;
                if (command.RecordedAt.HasValue) request.RecordedAt = command.RecordedAt;
                if (!string.IsNullOrEmpty(command.Source)) request.Source = command.Source;
                if (command.Metrics != null) request.Metrics = command.Metrics;

                var result = await _weatherService.UpdateWeatherDataAsync(command.Id, request);
                if (result)
                {
                    _logger.LogInformation("成功更新天气数据，ID: {WeatherDataId}", command.Id);
                }
                else
                {
                    _logger.LogWarning("天气数据不存在，ID: {WeatherDataId}", command.Id);
                }
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新天气数据失败，ID: {WeatherDataId}", command.Id);
                throw;
            }
        }
    }

    public class DeleteWeatherDataCommandHandler : ICommandHandler<DeleteWeatherDataCommand, bool>
    {
        private readonly IWeatherService _weatherService;
        private readonly ILogger<DeleteWeatherDataCommandHandler> _logger;

        public DeleteWeatherDataCommandHandler(IWeatherService weatherService, ILogger<DeleteWeatherDataCommandHandler> logger)
        {
            _weatherService = weatherService;
            _logger = logger;
        }

        public async Task<bool> HandleAsync(DeleteWeatherDataCommand command)
        {
            try
            {
                var result = await _weatherService.DeleteWeatherDataAsync(command.Id);
                if (result)
                {
                    _logger.LogInformation("成功删除天气数据，ID: {WeatherDataId}", command.Id);
                }
                else
                {
                    _logger.LogWarning("天气数据不存在，ID: {WeatherDataId}", command.Id);
                }
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除天气数据失败，ID: {WeatherDataId}", command.Id);
                throw;
            }
        }
    }

    public class CollectWeatherDataCommandHandler : ICommandHandler<CollectWeatherDataCommand, WeatherDataEntry>
    {
        private readonly IWeatherService _weatherService;
        private readonly ILogger<CollectWeatherDataCommandHandler> _logger;

        public CollectWeatherDataCommandHandler(
            IWeatherService weatherService,
            ILogger<CollectWeatherDataCommandHandler> logger)
        {
            _weatherService = weatherService;
            _logger = logger;
        }

        public async Task<WeatherDataEntry> HandleAsync(CollectWeatherDataCommand command)
        {
            try
            {
                var weatherData = await _weatherService.CollectWeatherDataAsync(command.CityId);
                _logger.LogInformation("成功采集天气数据，城市ID: {CityId}", command.CityId);
                return weatherData;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "采集天气数据失败，城市ID: {CityId}", command.CityId);
                throw;
            }
        }
    }

    public class SimulateWeatherDataCommandHandler : ICommandHandler<SimulateWeatherDataCommand, SimulateWeatherDataResult>
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ILogger<SimulateWeatherDataCommandHandler> _logger;

        public SimulateWeatherDataCommandHandler(
            IUnitOfWork unitOfWork,
            ILogger<SimulateWeatherDataCommandHandler> logger)
        {
            _unitOfWork = unitOfWork;
            _logger = logger;
        }

        public async Task<SimulateWeatherDataResult> HandleAsync(SimulateWeatherDataCommand command)
        {
            try
            {
                // 简单实现：直接返回模拟结果，不生成实际数据
                var cities = await _unitOfWork.WeatherData.GetAllAsync();
                var cityList = cities.Cast<City>().ToList();

                var result = new SimulateWeatherDataResult
                {
                    CityCount = cityList.Count,
                    TotalDataGenerated = cityList.Count * command.Count,
                    BaseTemperature = command.BaseTemperature,
                    CountPerCity = command.Count,
                    Cities = cityList.Select(c => new { c.Id, c.Name, c.Country }).Cast<object>().ToList()
                };

                _logger.LogInformation("模拟天气数据生成计算完成，城市数: {CityCount}，预计数据量: {TotalCount}", 
                    result.CityCount, result.TotalDataGenerated);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "模拟生成天气数据失败");
                throw;
            }
        }
    }
}